package com.atguigu.gmall.seckill.consumer;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.mapper.SeckillMapper;
import com.atguigu.gmall.seckill.mapper.SeckillOrderMapper;
import com.atguigu.gmall.seckill.pojo.SeckillOrder;
import com.atguigu.gmall.seckill.pojo.UserRecode;
import com.atguigu.gmall.seckill.service.SeckillService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;

import java.util.Map;
/**
 * 秒杀订单的监听类
 */
public class SeckillOrderUpdateListener {
    @Autowired
    private SeckillService seckillService;
    /**
     * 监听发生了支付行为的秒杀订单:消息的生产者是支付微服务
     * @param msg
     */
    @RabbitListener(queues = "seckill_queue")
    public void updateSeckillOrder(String msg){
        //将消息的类型转换为map的数据
        Map<String,String> payResult = JSONObject.parseObject(msg, Map.class);
        String payway = payResult.get("payway");
        if (payway.equals("0")) {
            //支付宝支付逻辑
            Map<String, String> map = JSONObject.parseObject(msg, Map.class);
            //进行解析,获取请求结果
            String tradeStatus = map.get("trade_status");
            if (!StringUtils.isEmpty(tradeStatus) && tradeStatus.equals("TRADE_SUCCESS")) {
                //支付成功
                seckillService.paySuccess(map);
                return;
            }
            //支付失败
            seckillService.payFail(map);
        }else {
            //微信支付逻辑
            String returnCode = payResult.get("return_code");
            if (returnCode.equals("SUCCESS")){
                //获取交易的结果
                String resultCode = payResult.get("result_code");
                if(resultCode.equals("SUCCESS")){
                    //支付成功,修改订单的状态
                    seckillService.paySuccess(payResult);
                    return;
                }
            }
            //支付失败,修改订单的状态
            seckillService.payFail(payResult);
        }
    }

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SeckillOrderMapper seckillOrderMapper;
    /**
     * 监听超时未支付的订单的延迟消息:秒杀的下单服务发送的消息
     * @param msg
     */
    @RabbitListener(queues = "seckill_queue")
    public void cancleSeckillOrder(String msg){
        //数据类型的转换
        SeckillOrder seckillOrder = JSONObject.parseObject(msg, SeckillOrder.class);
        //取消订单
        //判断前置状态
        if (seckillOrder != null && seckillOrder.getStatus().equals("0")){
            //修改订单状态
            seckillOrder.setStatus("3");
            //修改redis中的订单的状态
            String username = seckillOrder.getUserId();
            redisTemplate.boundHashOps("SeckillOrder_" + username).put(seckillOrder.getId(),seckillOrder);
            //将订单的信息存入数据库
            seckillOrderMapper.insert(seckillOrder);
            //库存回滚   1.redis回滚 2.数据库回滚
            UserRecode userRecode = (UserRecode)redisTemplate.boundValueOps("SeckillStatus_" + username).get();
            rollBackSeckillGoodsNum(userRecode.getGoodsId(), userRecode.getTime(), userRecode.getNum());
            //排队标识删除掉
            redisTemplate.delete("SeckillUserQueue_" + username);
            //排队状态可以删掉了
            redisTemplate.delete("SeckillStatus_" + username);
        }
    }
    @Autowired
    private SeckillMapper seckillGoodsMapper;
    /**
     * 回滚秒杀商品的库存
     */
    private void rollBackSeckillGoodsNum(String skuId, String time, Integer num) {
        //  //从redis中获取商品的数据
        SeckillGoods seckillGoods =
                (SeckillGoods)redisTemplate.boundHashOps("SeckillGoods_" + time).get(skuId);
        if(seckillGoods == null){
            //商品已经售罄了--更新数据库中的库存数据
            seckillGoodsMapper.updateSeckillGoodsStock(skuId, num);
        }else{
            //redis中还有数据--更新redis中的库存数据
            String[] seckillGoodsQueue = getSeckillGoodsQueue(skuId, num);
            redisTemplate.boundListOps("seckillGoodsQueue_" + skuId).leftPushAll(seckillGoodsQueue);
            //回滚库存的对象
            redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(skuId, num);
        }

    }

    /**
     * 构建商品库存个数长度的数组
     * @param goodsId
     * @param stockCount
     * @return
     */
    private String[] getSeckillGoodsQueue(String goodsId, Integer stockCount){
        //构建一个库存长度的数组
        String[] ids = new String[stockCount];
        //元素填充
        for (int i = 0; i < stockCount; i++) {
            ids[i] = goodsId;
        }
        //返回数据
        return ids;
    }
}
